package com.chak.voyage.crawler.processor.lvmama;

import com.chak.voyage.data.entity.TNote;
import com.chak.voyage.utils.HtmlFormatterUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Selectable;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by delzh on 2016/9/4.
 */
public class LvmamaProcessor implements PageProcessor{

    public static final Integer CONTENTTYPE = 1;

    private static Logger LOG = LoggerFactory.getLogger(LvmamaProcessor.class);

    private Site site = Site.me().setRetryTimes(10).setSleepTime(3000);

    private final static String [] acceptPatterns = new String[]{
            "http://www.lvmama.com/trip/show/[0-9]*$",
            "http://www.lvmama.com/lvyou/youji/.*$",
            "http://www.lvmama.com/lvyou/poi/sight-.*.html",
            "http://www.lvmama.com/lvyou/scenery/((?!/).)*.html",
            "http://www.lvmama.com/lvyou/((?!/).)*.html"
    };

    private static List<Pattern> accept = new ArrayList<Pattern>();

    static {
        for (String rej : acceptPatterns){
            Pattern pattern = Pattern.compile(rej);
            accept.add(pattern);
        }
    }
    public void process(Page page) {
        List<String> urls = page.getHtml().links().regex("http://www.lvmama.com/.*$").all();
        for (String url : urls){
            int priority = getPriority(url);
            //优先级大于0说明是符合accept规则的url,加入爬取列表
            if (priority > 0){
                Request request = new Request(url)
                        .setPriority(priority)
                        .putExtra("type",priority);
                page.addTargetRequest(request);
            }
        }
        if (!isCrawlUrl(page.getUrl().get())) {
            LOG.info("爬取无效url:{}", page.getUrl().get());
            return;
        }
        String title = page.getHtml().xpath("//h1[@class='eh-text']/text()").get();
        String writerUrl = page.getHtml().xpath("//a[@class='eh-author']").get();
        String startDateStr = page.getHtml().xpath("//p[@class='ebsid-text'][1]/b/text()").get();
        String endDateStr = page.getHtml().xpath("//p[@class='ebsid-text'][2]/b/text()").get();
        String headerTab = page.getHtml().xpath("//p[@class='eh-sundry']/text()").get().trim();
        List<String> arr = Arrays.asList(headerTab.split("  "));

        StringBuffer stringBuffer = new StringBuffer();

        String forward = page.getHtml().xpath("//div[@class='ebma-foreword js-reply-comment']/html()").get();
        stringBuffer.append("<div>")
                .append(forward)
                .append("</div>");
        List<Selectable> allDate = page.getHtml().xpath("//div[@class='ebma-day']").nodes();
        for (Selectable selectable : allDate){
            String subDate = selectable.xpath("//em[@class='ebmad-title']/text()").get();
            List<Selectable> list = selectable.xpath("//div[@class='ebma-area']").nodes();
            stringBuffer.append("<h2>")
                    .append(subDate)
                    .append("</h2>");
            if (list.size() == 1){
                String position = selectable.xpath("//div[@class='ebma-title']/span/html()").get();
                String intro = selectable.xpath("//div[@class='ebma-post js-reply-comment']/html()").get();
                position = HtmlFormatterUtil.removeTag(position);
                stringBuffer.append("<div>")
                        .append("位置:")
                        .append(position)
                        .append("</div>");
                stringBuffer.append("<div>")
                        .append(intro)
                        .append("</div>");
//                LOG.info("subDate: {}, position:{}, intro: {}", subDate,position,intro);
            }
            else if (list.size() == 2){
                String position = list.get(1).xpath("//div[@class='ebma-title']/html()").get();
                String intro = list.get(0).xpath("//div[@class='ebmal-text js-reply-comment']/text()").get();
                position = HtmlFormatterUtil.removeTag(position);
                stringBuffer.append("<div>")
                        .append("位置:")
                        .append(position)
                        .append("</div>");
                stringBuffer.append("<div>")
                        .append(intro)
                        .append("</div>");
//                LOG.info("subDate: {}, position:{}, intro: {}", subDate,position,intro);
            }

            List<Selectable> allPart = selectable.xpath("//div[@class='ebma-area']//div[@class='ebma-picture']").nodes();
            StringBuffer mainContent = new StringBuffer();
            for (Selectable part : allPart){
                String picture = part.xpath("//div[@class='ebma-picture']/img/outerHtml()").regex("http://.*\\.jpg").get();
                String picComment = part.xpath("div[@class='ebmaf-text js-reply-comment']/text()").get();
                mainContent.append("<div>")
                        .append("<img src=\"")
                        .append(picture)
                        .append("\"/>")
                        .append("<span>")
                        .append(picComment)
                        .append("</span>")
                        .append("</div>")
                        .append("</br>");
//                LOG.info("pic: {}, comment: {}", picture, picComment);
            }
            stringBuffer.append(mainContent);
        }
        String likeCount = page.getHtml().xpath("//a[@class='ehf-button ehf-praise  nlogin']/b/text()").get();
//        LOG.info("url:{}, title: {}, writerUrl: {}, startDateStr: {}, endDateStr: {}, arr: {}, " +
//                "likeCount: {}",
//                page.getUrl(), title, writerUrl, startDateStr, endDateStr, arr, likeCount);
        TNote note = new TNote();
        note.setTitle(title);
        note.setWriterUrl(writerUrl);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            note.setStartDate(simpleDateFormat.parse(startDateStr));
            note.setEndDate(simpleDateFormat.parse(endDateStr));
        } catch (ParseException e) {
            LOG.warn("Found error date string, url: {}, error: {}", page.getUrl(), Arrays.toString(e.getStackTrace()));
        }
        try {
            note.setLikeCount(Integer.valueOf(likeCount));
        } catch (NumberFormatException e) {
            LOG.warn("Format like count error, url:{}, error:{}", page.getUrl(), Arrays.toString(e.getStackTrace()));
        }
        note.setContent(stringBuffer.toString());
        note.setUrl(page.getUrl().get());
        note.setType(CONTENTTYPE);
        note.setContentId(Integer.valueOf(note.getUrl().substring(note.getUrl().lastIndexOf("/") + 1)));
        note = decorateArr(note,arr);
        page.putField("note",note);
    }

    private TNote decorateArr(TNote note, List<String> arr){
        String[] patterns = new String[]{"于.*发布","[0-9]+天",".*出行",".*[0-9]+元","浏览[0-9]+次"};
        String[] contents = new String[patterns.length];
        for (String str : arr){
            for (int i = 0; i < patterns.length; i++) {
                Pattern pattern = Pattern.compile(patterns[i]);
                Matcher matcher = pattern.matcher(str);
                if (matcher.find()) {
                    contents[i] = matcher.group(0);
                }
            }
        }
        if (StringUtils.isNotBlank(contents[0])) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            try {
                note.setWriteTime(simpleDateFormat.parse(contents[0].substring(1, contents[0].length() - 2)));
            } catch (ParseException e) {
                LOG.warn("Fail to parse create date!");
            }
        }
        if (StringUtils.isNotBlank(contents[3])) {
            String money = contents[3].substring(4, contents[3].length() - 1);
            note.setMoney(Integer.valueOf(money));
        }
        if (StringUtils.isNotBlank(contents[4])) {
            String viewerCount = contents[4].substring(2, contents[4].length() - 1);
            note.setViewerCount(Integer.valueOf(viewerCount));
        }
        return note;
    }

    /**
     * 是否为目标页面
     * @param url
     * @return
     */
    private boolean isCrawlUrl(String url){
        Pattern pattern = Pattern.compile("http://www.lvmama.com/trip/show/[0-9]*$");
        return pattern.matcher(url).find();
    }

    /**
     * 获取url优先级
     * @param url
     * @return 根据accept的顺序越往前优先级越大
     */
    public int getPriority(String url){
        String [] noInclude = new String[]{"#","?"};
        for (String str : noInclude){
            if (url.contains(str))
                return 0;   //包含非法字符，优先级设为0，抛弃之
        }
        int tmp = accept.size();
        for (int i = 0; i < accept.size(); i++){
            Pattern pattern = accept.get(i);
            Matcher matcher = pattern.matcher(url);
            if (matcher.find()){
                tmp = i;
            }
        }
        return accept.size() - tmp;
    }

    public Site getSite() {
        return site;
    }
}
